package com.qf.smartplatform.events.listeners;


import com.qf.smartplatform.dto.R;
import com.qf.smartplatform.events.UserLoginEvent;
import com.qf.smartplatform.mapper.LoginInforMapper;
import com.qf.smartplatform.mapper.UserOnlineMapper;
import com.qf.smartplatform.pojo.Logininfor;
import com.qf.smartplatform.pojo.User;
import com.qf.smartplatform.pojo.UserOnline;
import com.qf.smartplatform.service.UserService;
import com.qf.smartplatform.utils.RequestUtil;
import com.qf.smartplatform.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * Created by Jackiechan on 2021/12/30/10:22
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Component
public class UserloginListener {

    private UserService userService;

    private UserOnlineMapper userOnlineMapper;

    private LoginInforMapper loginInforMapper;

    @Autowired
    public void setLoginInforMapper(LoginInforMapper loginInforMapper) {
        this.loginInforMapper = loginInforMapper;
    }

    @Autowired
    public void setUserOnlineMapper(UserOnlineMapper userOnlineMapper) {
        this.userOnlineMapper = userOnlineMapper;
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    /**
     * 更新用户的基本登录信息
     * @param loginEvent
     */
    @EventListener
   // @Async
    public void upDateUserInfo(UserLoginEvent loginEvent) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        User user = SecurityUtils.getUser();
        //通过异步执行当前操作,内部有自己的线程池
        CompletableFuture.runAsync(()->{//runAsync是不需要结果的异步
                    try {
                    //  Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);//存放了是请求的系统和软件信息
                    String ip = RequestUtil.getRemoteHost(request);//获取到用户的ip
                    //  user.setLastLogin(user.getCurrentLogin());
                    user.setCurrentLogin(new Date());
                    // user.setLastLoginIp(user.getCurrentLoginIp());
                    user.setCurrentLoginIp(ip);
                    userService.updateUserLogin(user);
                } catch (Exception e) {
                    e.printStackTrace();
                }
        });
//        new Thread() {
//            @Override
//            public void run() {
//                try {
//                    //  Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);//存放了是请求的系统和软件信息
//                    String ip = RequestUtil.getRemoteHost(request);//获取到用户的ip
//                    //  user.setLastLogin(user.getCurrentLogin());
//                    user.setCurrentLogin(new Date());
//                    // user.setLastLoginIp(user.getCurrentLoginIp());
//                    user.setCurrentLoginIp(ip);
//                    userService.updateUserLogin(user);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }.start();
    }

    /**
     * 更新用户的在线状态
     * @param loginEvent
     */
    @EventListener
    //@Async
    public void upDateUserOnline(UserLoginEvent loginEvent) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        User user = SecurityUtils.getUser();

            CompletableFuture.runAsync(()->{
                try {
                    Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);//存放了是请求的系统和软件信息
                    String ip = RequestUtil.getRemoteHost(request);//获取到用户的ip
                    UserOnline userOnline = new UserOnline();
                    userOnline.setSessionId(request.getSession().getId());
                    userOnline.setLoginName(user.getUsername());
                    userOnline.setStartTimestamp(new Date());
                    userOnline.setStatus("1");//设置为在线
                    userOnline.setIpaddr(ip);
                    userOnline.setLoginLocation(RequestUtil.getLocationByIp(ip));//请求第三方服务器,需要时间,所以应该放到单独的线程中执行
                    userOnline.setOs(osAndBrowserInfo.get("os"));
                    userOnline.setBrowser(osAndBrowserInfo.get("browser"));
                    userOnline.setExpireTime(30L);
                    //保存到数据库,发现有问题,当前用户的数据如果已经存在了 应该更新
                    UserOnline currentLogin = userOnlineMapper.selectByLoginName(user.getUsername());//先查询一下
                    if (currentLogin != null) {
                        //存在,删除
                        userOnlineMapper.deleteByLoginName(user.getUsername());
                    }
                    userOnlineMapper.addOnlineData(userOnline);
                }catch (Exception e){
                   e.printStackTrace();
                }
            });

    }

    /**
     * 更新登陆日志
     * @param loginEvent
     */
    @EventListener
    //@Async
    public void onLoginLog(UserLoginEvent loginEvent) throws UnsupportedEncodingException {
        //TODO 交给你们写
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        User user = SecurityUtils.getUser();

        CompletableFuture.runAsync(()->{
            try {
                Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);//存-+放了是请求的系统和软件信息
                String ip = RequestUtil.getRemoteHost(request);//获取到用户的ip
                Logininfor logininfor=new Logininfor();
                logininfor.setLoginName(user.getUsername());
                logininfor.setIpaddr(ip);
                logininfor.setLoginTime(new Date());
                String GBK = RequestUtil.getLocationByIp(ip);
                byte[] bytes = GBK.getBytes("GBK");
                String loginLocation =new String(bytes, "UTF-8");
                logininfor.setLoginLocation(loginLocation);//请求第三方服务器,需要时间,所以应该放到单独的线程中执行
                logininfor.setOs(osAndBrowserInfo.get("os"));
                logininfor.setBrowser(osAndBrowserInfo.get("browser"));
                //保存到数据库,发现有问题,当前用户的数据如果已经存在了 应该更新
                R r = loginEvent.getR();
                logininfor.setStatus(String.valueOf(r.getCode()));
                logininfor.setMsg(r.getMsg());
                loginInforMapper.addLoginInfor(logininfor);
            }catch (Exception e){
                e.printStackTrace();
            }
        });
    }
}
